package com.block.product.service.union;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.block.common.constant.AppRspCodeConstant;
import com.block.common.exception.BizException;
import com.block.common.service.LogFactory;
import com.block.common.util.LocalDateUtil;
import com.block.common.vo.ResponseVo;
import com.block.db.common.vo.BaseUserInfoVo;
import com.block.db.entity.ProductInfo;
import com.block.product.service.IUnionProductService;
import com.block.product.service.union.utils.ssd.Base64Utils;
import com.block.product.service.union.utils.ssd.RSAUtils;
import com.block.product.service.union.utils.ssd.RequestUtil51GJJ;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * 随时贷
 */
@Service
public class SuiShiDaiProductServiceImpl implements IUnionProductService {

    private static Logger log = LogFactory.getCommLog();

    @Override
    public ResponseVo matchUserInfo(ProductInfo productInfo, BaseUserInfoVo userInfoVo)  {

            String requestMatchUrl = productInfo.getChannelMatchUrl();
            String md5Mobile = SecureUtil.md5(userInfoVo.getMobile()).toLowerCase(Locale.ROOT);

            JSONObject bizMap = new JSONObject();
            bizMap.put("phone_md5", md5Mobile);
            bizMap.put("ip", userInfoVo.getIp());

//            String content = this.getContent(JSON.toJSONString(bizMap), productInfo.getPubKey());
//            String sign =  this.getSign(JSON.toJSONString(bizMap), productInfo.getPubKey(), productInfo.getPriKey());

        JSONObject jsonObject1 = RequestUtil51GJJ.encodeParam(bizMap, productInfo.getPubKey(), productInfo.getPriKey());

        Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("channel", productInfo.getChannelCode());
            paramMap.put("content", jsonObject1.getString("content"));
            paramMap.put("sign", jsonObject1.getString("sign"));

            log.info("【产品联登】【随时贷】撞库请求【REQUEST_URL】{}【bizMap】{}", requestMatchUrl, JSON.toJSONString(bizMap));
            HttpRequest httpRequest = HttpUtil.createPost(requestMatchUrl);
            httpRequest.header("Content-Type", "application/json");
            httpRequest.body(JSON.toJSONString(paramMap));
            String resultStr = httpRequest.execute().body();
            log.info("【产品联登】【随时贷】撞库完成【resultStr】{}", resultStr);

            JSONObject jsonObject = JSON.parseObject(resultStr);

        JSONObject resultObject = RequestUtil51GJJ.decodeParam(jsonObject, productInfo.getPubKey(), productInfo.getPriKey());

            String code = resultObject.getString("code");
            if (StrUtil.equals("0000", code)){
                return new ResponseVo(AppRspCodeConstant.SUCCESS);
            }
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION);
    }

    @Override
    public ResponseVo registerUserInfo(ProductInfo productInfo, BaseUserInfoVo userInfoVo) {

            String requestUrl = productInfo.getChannelRegisterUrl();
            String nowTime = LocalDateUtil.getDateFormatStr(LocalDateTime.now().minusSeconds(5L), LocalDateUtil.TOTAL_DATE_TIME);

            JSONObject bizMap = new JSONObject();
            bizMap.put("phone", userInfoVo.getMobile());
            bizMap.put("is_authorize", 1);
            bizMap.put("authorize_time", nowTime);

            JSONObject jsonObject1 = RequestUtil51GJJ.encodeParam(bizMap, productInfo.getPubKey(), productInfo.getPriKey());

            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("channel", productInfo.getChannelCode());
            paramMap.put("content", jsonObject1.getString("content"));
            paramMap.put("sign", jsonObject1.getString("sign"));

            log.info("【产品联登】【随时贷】联登请求【requestUrl】{}【bizMap】{}【paramMap】{}", requestUrl, JSON.toJSONString(bizMap), JSON.toJSONString(paramMap));
            HttpRequest httpRequest = HttpUtil.createPost(requestUrl);
            httpRequest.header("Content-Type", "application/json");
            httpRequest.body(JSON.toJSONString(paramMap));
            String resultStr = httpRequest.execute().body();
            log.info("【产品联登】【随时贷】联登完成【result】{}", resultStr);

            JSONObject jsonObject = JSON.parseObject(resultStr);

            JSONObject resultObject = RequestUtil51GJJ.decodeParam(jsonObject, productInfo.getPubKey(), productInfo.getPriKey());

            String code = resultObject.getString("code");
            String msg = resultObject.getString("msg");
            if (StrUtil.equals("0000", code)){

                String skipUrl = resultObject.getString("skip_url");
                JSONObject resultData=  new JSONObject();
                resultData.put("productUrl", skipUrl);

                return new ResponseVo(AppRspCodeConstant.SUCCESS, resultData);
            }
            return new ResponseVo(AppRspCodeConstant.THRID_FAILED, msg, "");
    }

    private String getContent(String bizMapContent, String pubKey) throws Exception {

        PublicKey publicKey = RSAUtils.loadPublicKey(pubKey);
        byte[] encryptByte = RSAUtils.encryptData(bizMapContent.getBytes("utf-8"), publicKey);
        // 为了方便观察把加密后的数据用base64加密转一下，要不然看起来是乱码,所以解密是也是要用Base64先转换
        String afterencrypt = Base64Utils.encode(encryptByte);
        return afterencrypt;
    }

    private String getSign(String bizMapContent, String pubKey, String priKey) throws Exception {
        System.out.println();
        System.out.println(bizMapContent);
        System.out.println();
        System.out.println(pubKey);
        System.out.println();
        System.out.println(priKey);
        System.out.println();
        // 从字符串中得到公钥
        PublicKey publicKey = RSAUtils.loadPublicKey(pubKey);

        byte[] encryptByte = RSAUtils.encryptData(bizMapContent.getBytes("utf-8"), publicKey);

        // 从字符串中得到私钥
        PrivateKey privateKey = RSAUtils.loadPrivateKey(priKey);
        // 加签
        String signStr = RSAUtils.rsaSign(encryptByte, privateKey);
        return signStr;
    }

}
